home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / UTILITIE / CPU_MEMO / 3468.ZIP / POPUP.ZIP / POPUP.ASM < prev    next >
Assembly Source File  |  1988-06-30  |  14KB  |  388 lines

  1. ;-----------------------------------------------------------------------------
  2. ; POPUP.ASM : A popup utility for linking with Microsoft 'C'
  3. ;-----------------------------------------------------------------------------
  4. ; Last Updated : 04/01/80
  5. ;-----------------------------------------------------------------------------
  6. ; Author : M.R.Watson. Copyright (C) M.R.Watson, 1987, 1988
  7. ;-----------------------------------------------------------------------------
  8. ; Synopsis
  9. ; ========
  10. ; This implements a function, "popup", which can be called by any small model
  11. ; Microsoft 'C' program. Calling is as follows :
  12. ; popup( int ScanCode, int ShiftCode )
  13. ; where ScanCode is the activating key's scan code, and ShiftCode is the
  14. ; combination of shift codes, as defined in documentation for interrupt 16H.
  15. ; This allows you to choose, for example, CTRL-ALT-ESC as the activating key.
  16. ; (Scan code = 1, shift code = 0CH)
  17. ; Once popup() has been called, as far as the program is concerned it returns
  18. ; after an unspecified period of time. What actually happens is that the
  19. ; program initialises various interrupt vectors, and then terminates and
  20. ; stays resident. When the activating key-sequence is pressed, the program
  21. ; interrupts, and control returns to the part of the program which just called
  22. ; popup() as if that function (popup()) had just returned.
  23. ; Then the program can proceed with the popup code as it sees fit.
  24. ; Note that the only DOS services which may be used are int 21H, function
  25. ; codes 0DH and above. This effectively precludes the use of DOS console IO.
  26. ; You must therefore use BIOS to do this, or write directly to video memory.
  27. ; In order to maintain compatiblity with Sidekick, et al, it is sensible to
  28. ; continuously issue interrupt 28H (background process), which Sidekick
  29. ; uses in the same way as this program.
  30. ;
  31. ; Note that this program uses two undocumented features of MS-DOS :
  32. ;
  33. ; (1) Interrupt 28H. This is called continuously by int 21H func 0AH
  34. ;     (buffered input), and hence by anything which calls func 0AH.
  35. ;     When this interrupt is recieved, any DOS function HIGHER that 0CH
  36. ;     may be freely called.
  37. ; (2) Int 21H, func 34H. Returns ES:BX pointing to a byte which is the DOS
  38. ;     busy flag. When this flag is TRUE (non-zero), DOS is busy and shouldn't
  39. ;     be interrupted. When it is false (0), any DOS function may be called.
  40. ; A combination of these two features is used to enable the popup() function
  41. ; to popup without conflict at the earliest possible moment.
  42. ;
  43. ; NOTE: It is a good idea to EXEMOD the resulting program, and change the
  44. ; maximum paragraph allocation in order to make it take up less memory.
  45. ;-----------------------------------------------------------------------------
  46. ; EXAMPLE :
  47. ;
  48. ;       FOREVER
  49. ;       {
  50. ;               popup( ScanCode, ShiftStatus );
  51. ;               HandlePopup();
  52. ;       }
  53. ;-----------------------------------------------------------------------------
  54. ; Assembly notes:
  55. ; ---------------
  56. ; This is compiled with MASM 5.0. To use an earlier version, you will have to
  57. ; define the code and data segments in the usual way. Also, one line
  58. ; (the .MODEL directive) must be removed from the file CLINK.INC
  59. ; (The CLINK.INC header may also be useful in other assembly programs.)
  60. ;-----------------------------------------------------------------------------
  61.  
  62.  
  63. PUBLIC  _popup
  64.  
  65. include CLINK.INC
  66.  
  67.  
  68. .DATA
  69.         EXTRN   __psp:WORD
  70.  
  71. .CODE
  72.  
  73. OldKeyboard     LABEL   DWORD           ; Old keyboard interrupt address
  74. oldint9h        dw 2 dup (?)
  75. OldTimer        LABEL   DWORD           ; Old timer interrupt address
  76. oldint1ch       dw 2 dup (?)
  77. OldDisk         LABEL   DWORD           ; Old disk service interrupt address
  78. oldint13h       dw 2 dup (?)
  79. OldBackground   LABEL   DWORD           ; Old background process int address
  80. oldint28h       dw 2 dup (?)
  81.  
  82. ScanCode        db      0       ; Scan code of activating key.
  83. ShiftCode       db      0       ; Shift status required for activation.
  84. PopupActive     db      0       ; Set to 0FFH when popup is active.
  85. PopupWanted     db      0       ; Set to 0FFH when popup wanted.
  86. DiskActive      db      0       ; Set to 0FFH when disk is active (Int 13H)
  87. installed       db      0       ; Set to 0FFH after Popup is installed
  88.  
  89. DosSegment      dw      ?
  90. BusyFlag        dw      ?
  91.  
  92. PopAX           dw      ?
  93. PopBX           dw      ?
  94. PopCX           dw      ?
  95. PopDX           dw      ?
  96. PopSI           dw      ?
  97. PopDI           dw      ?
  98. PopSS           dw      ?
  99. PopSP           dw      ?
  100. PopBP           dw      ?
  101. PopDS           dw      ?
  102. PopES           dw      ?
  103.  
  104. DosAX           dw      ?
  105. DosBX           dw      ?
  106. DosCX           dw      ?
  107. DosDX           dw      ?
  108. DosSI           dw      ?
  109. DosDI           dw      ?
  110. DosSS           dw      ?
  111. DosSP           dw      ?
  112. DosBP           dw      ?
  113. DosDS           dw      ?
  114. DosES           dw      ?
  115.  
  116.  
  117. ;-----------------------------------------------------------------------------
  118. ; Keyboard Interrupt Handler (Interrupt 09H)
  119. ;-----------------------------------------------------------------------------
  120.  
  121. keyboard        PROC NEAR
  122.  
  123.         sti                             ; Enable interrupts
  124.         push    ax
  125.         in      al, 60H                 ; Get keyboard scan code
  126.         cmp     al, ScanCode            ; Matches ScanCode ?
  127.         jne     CallKeyboard            ; No - Call original routine
  128.         mov     ah, 2                   ; BIOS func : Check shift status
  129.         int     16H                     ; Call it...
  130.         and     al, 15                  ; Ignore numlock etc
  131.         cmp     al, ShiftCode           ; Matches ShiftCode ?
  132.         jne     CallKeyboard            ; No - Call original routine
  133.         call    ResetKeyboard           ; Actuator, so remove from keyboard.
  134.         pop     ax
  135.         cmp     PopupActive, 0FFH       ; Popup already active?
  136.         je      KeyDone                 ; No more to do if so.
  137.         mov     PopupWanted, 0FFH       ; Else set request flag.
  138.  
  139. KeyDone:
  140.  
  141.         iret
  142.  
  143.  
  144. CallKeyboard:
  145.  
  146.         pop     ax
  147.         jmp     OldKeyboard             ; Call original int 9 handler, which
  148.                                         ; will do it's own iret.
  149.  
  150. keyboard        ENDP
  151.  
  152.  
  153. ;-----------------------------------------------------------------------------
  154. ; Timer Interrupt handler (Interrupt 1CH)
  155. ;-----------------------------------------------------------------------------
  156.  
  157. timer   PROC    NEAR
  158.  
  159.         pushf
  160.         call    OldTimer
  161.         cmp     PopupWanted, 0                  ; Is a popup requested ?
  162.         je      TimerExit
  163.         push    es
  164.         push    di
  165.         mov     es, DosSegment                  ; Get seg:off of busy flag
  166.         mov     di, BusyFlag
  167.         cmp     BYTE PTR es:[di], 0             ; Is DOS busy?
  168.         pop     di
  169.         pop     es
  170.         jne     TimerExit                       ; If so, don't pop up
  171.         cmp     DiskActive, 0                   ; Is a disk service active?
  172.         jne     TimerExit                       ; If so, don't pop up
  173.         push    ax
  174.         mov     al, 20H
  175.         out     20H, al                         ; Issue EOI to 8259 PIC
  176.         pop     ax
  177.         mov     PopupWanted, 0
  178.         call    poppit                  ; Call the actual popup routine
  179.  
  180. TimerExit:
  181.  
  182.         iret
  183.  
  184. timer   ENDP
  185.  
  186.  
  187. ;-----------------------------------------------------------------------------
  188. ; Disk Service Interrupt Handler (Interrupt 13H)
  189. ;-----------------------------------------------------------------------------
  190.  
  191. DiskService     PROC    NEAR
  192.  
  193.         inc     DiskActive
  194.         pushf
  195.         call    OldDisk
  196.         dec     DiskActive
  197.         iret
  198.  
  199. DiskService     ENDP
  200.  
  201.  
  202. ;-----------------------------------------------------------------------------
  203. ; Background Process Interrupt Handler (Interrupt 28H)
  204. ;-----------------------------------------------------------------------------
  205.  
  206. background      PROC    NEAR
  207.  
  208.         pushf
  209.         call    OldBackground
  210.         cmp     PopupWanted, 0          ; Want to popup ?
  211.         je      BackgroundExit          ; No - Exit
  212.         mov     PopupWanted, 0          ; Reset popup wanted flag
  213.         call    poppit                  ; Call the actual popup routine
  214.  
  215. BackgroundExit:
  216.  
  217.         iret
  218.  
  219. background      ENDP
  220.  
  221.  
  222. ;-----------------------------------------------------------------------------
  223. ; ResetKeyboard : Does just that.
  224. ;-----------------------------------------------------------------------------
  225.  
  226. ResetKeyboard   PROC    NEAR
  227.  
  228.         in      al, 61H         ; Get current control value
  229.         mov     ah, al
  230.         or      al, 80H         ; Set high bit
  231.         out     61H, al         ; Send to control port
  232.         mov     al, ah          ; Recover original value
  233.         out     61h, al         ; And send it
  234.         cli
  235.         mov     al, 20H
  236.         out     20H, al         ; Send EOI to 8259 PIC
  237.         sti
  238.         ret
  239.  
  240. ResetKeyboard   ENDP
  241.  
  242.  
  243. ;-----------------------------------------------------------------------------
  244. ; poppit : This is the routine called when a popup has been requested.
  245. ;-----------------------------------------------------------------------------
  246.  
  247. poppit  PROC    NEAR
  248.  
  249.         mov     PopupActive, 0FFH
  250.         sti
  251.         mov     WORD PTR DosAX, ax      ; Save Dosup register block
  252.         mov     WORD PTR DosBX, bx
  253.         mov     WORD PTR DosCX, cx
  254.         mov     WORD PTR DosDX, dx
  255.         mov     WORD PTR DosSI, si
  256.         mov     WORD PTR DosDI, di
  257.         mov     WORD PTR DosSP, sp
  258.         mov     WORD PTR DosBP, bp
  259.         mov     WORD PTR DosSS, ss
  260.         mov     WORD PTR DosES, es
  261.         mov     WORD PTR DosDS, ds
  262.         mov     ax, WORD PTR PopAX
  263.         mov     bx, WORD PTR PopBX
  264.         mov     cx, WORD PTR PopCX
  265.         mov     dx, WORD PTR PopDX
  266.         mov     si, WORD PTR PopSI
  267.         mov     di, WORD PTR PopDI
  268.         mov     bp, WORD PTR PopBP
  269.         cli
  270.         mov     sp, WORD PTR PopSP
  271.         mov     ss, WORD PTR PopSS
  272.         sti
  273.         mov     es, WORD PTR PopES
  274.         mov     ds, WORD PTR PopDS
  275.         ret
  276.  
  277. poppit  ENDP
  278.  
  279. ;-----------------------------------------------------------------------------
  280. ; Entry point for calls to Popup() : Initialise if necessary.
  281. ;-----------------------------------------------------------------------------
  282. ; Example usage :
  283. ;
  284. ; FOREVER
  285. ; {
  286. ;     popup(ScanCode,ShiftCode);
  287. ;     /* Code to handle popup */
  288. ; }
  289. ;-----------------------------------------------------------------------------
  290.  
  291. _popup  PROC    NEAR
  292.  
  293.         mov     PopupActive, 0FFH       ; Just in case of timer ints.
  294.         mov     WORD PTR PopAX, ax      ; Save Popup register block
  295.         mov     WORD PTR PopBX, bx
  296.         mov     WORD PTR PopCX, cx
  297.         mov     WORD PTR PopDX, dx
  298.         mov     WORD PTR PopSI, si
  299.         mov     WORD PTR PopDI, di
  300.         mov     WORD PTR PopSP, sp
  301.         mov     WORD PTR PopBP, bp
  302.         mov     WORD PTR PopSS, ss
  303.         mov     WORD PTR PopES, es
  304.         mov     WORD PTR PopDS, ds
  305.         cmp     installed, 0            ; Already installed ?
  306.         je      install                 ; No - So go to it
  307.         mov     ax, WORD PTR DosAX
  308.         mov     bx, WORD PTR DosBX
  309.         mov     cx, WORD PTR DosCX
  310.         mov     dx, WORD PTR DosDX
  311.         mov     si, WORD PTR DosSI
  312.         mov     di, WORD PTR DosDI
  313.         mov     bp, WORD PTR DosBP
  314.         cli
  315.         mov     sp, WORD PTR DosSP
  316.         mov     ss, WORD PTR DosSS
  317.         sti
  318.         mov     es, WORD PTR DosES
  319.         mov     ds, WORD PTR DosDS
  320.         mov     PopupActive, 0
  321.         ret
  322.  
  323. install:
  324.  
  325. DEFARGS         scan, WORD, shift, WORD
  326.  
  327.         push    ds
  328.         push    cs
  329.         pop     ds
  330.         mov     installed, 0FFH
  331.         MOVARG  ax, scan                ; Save activator key codes
  332.         mov     ScanCode, al
  333.         MOVARG  ax, shift
  334.         mov     ShiftCode, al
  335.         mov     ah, 34H         ; Undocumented DOS function! Get busy flag.
  336.         int     21H             ; Returns es:[BX] = Busy flag
  337.         mov     DosSegment, es  ; So save for later usage
  338.         mov     BusyFlag, bx
  339.         mov     ah, 35h         ; DOS func: Get interrupt vector
  340.         mov     al, 09h         ; Get vector 09H
  341.         int     21h
  342.         mov     oldint9h, bx    ; And save here
  343.         mov     oldint9h[2], es
  344.         mov     ah, 25H         ; DOS func: Set interrupt vector
  345.         lea     dx, keyboard
  346.         int     21H
  347.         mov     ah, 35H         ; Save & set timer interrupt vector
  348.         mov     al, 1cH
  349.         int     21h
  350.         mov     oldint1ch, bx
  351.         mov     oldint1ch[2], es
  352.         mov     ah, 25h
  353.         lea     dx, timer
  354.         int     21h
  355.         mov     ah, 35h         ; Save & set disk service interrupt vector
  356.         mov     al, 13h
  357.         int     21h
  358.         mov     oldint13h, bx
  359.         mov     oldint13h[2], es
  360.         mov     ah, 25h
  361.         lea     dx, DiskService
  362.         int     21h
  363.         mov     ah, 35h         ; Save & set background process int. vector
  364.         mov     al, 28h
  365.         int     21h
  366.         mov     oldint28h, bx
  367.         mov     oldint28h[2], es
  368.         mov     ah, 25h
  369.         lea     dx, background
  370.         int     21h
  371.         pop     ds
  372.         mov     ah,31h          ; load keep process code
  373.         mov     al,0            ; load normal termination
  374.         mov     es, __psp
  375.         mov     dx, es:[2]
  376.         mov     bx, cs
  377.         sub     dx, bx
  378.         add     dx, 10H
  379.         inc     dx
  380.         mov     PopupActive, 0
  381.         pop     bp              ; Was pushed by DEFARGS macro
  382.         int     21h             ; terminate and stay resident
  383.  
  384. _popup  ENDP
  385.  
  386. END
  387.  
  388.